[数据平台]03 数据仓库之离线-Hive 三

进入命令行、常用基本命令、DDL、DML、常用函数

Posted by 李玉坤 on 2018-04-12

进入命令行

1、可以直接hive命令进入
2、可以通过HS2服务进入

1
2
3
4
5
6
7
8
9
HiveServer2 = HS2
HS2 :Server
默认端口号是10000
当然还可以改成10086等其他的
hiveserve2 --hiveconf hive.server2.thrift.port=10086
启动:$HIVE_HOME/bin下的 ./hiveserve2
beeline:Client Hive/Spark
启动beeline时,建议先cd $HIVE_HOME/bin中去
./beeline -u jdbc:hive2://ruozedata001:10086/ruozedata_hive -n hadoop

常用基本命令

1
2
3
4
5
6
7
8
9
10
11
!clear; 清屏命令
exit; 退出命令
use dbname; 切换到dbname所在数据库
show tables; 查看当前数据库下的所有表
创建表:create table stu(id int, name string, age int);
查看表结构:
desc stu;
desc extended stu;
desc formatted stu;
插入数据:insert into stu values(1,'pk',30);
查询数据:select * from stu;

DDL

emp.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
编号|名称|岗位|上级领导编号|入职时间|工资|津贴|部门编号
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981-2-22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981-4-2 2975.00 20
7654 MARTIN SALESMAN 7698 1981-9-28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30
7782 CLARK MANAGER 7839 1981-6-9 2450.00 10
7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20
7839 KING PRESIDENT 1981-11-17 5000.00 10
7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987-5-23 1100.00 20
7900 JAMES CLERK 7698 1981-12-3 950.00 30
7902 FORD ANALYST 7566 1981-12-3 3000.00 20
7934 MILLER CLERK 7782 1982-1-23 1300.00 10
8888 HIVE PROGRAM 7839 1988-1-23 10300.00

创建表

Hive中有两种常见类型的表:
内部表 MANAGED TABLE
外部表 EXTERNAL TABLE
内部表删除时: HDFS + META 都被删除
外部表删除时: HDFS不删除 仅META被删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name    -- (Note: TEMPORARY available in Hive 0.14.0 and later)
[(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[SKEWED BY (col_name, col_name, ...) -- (Note: Available in Hive 0.10.0 and later)]
ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
[STORED AS DIRECTORIES]
[
[ROW FORMAT row_format]
[STORED AS file_format]
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)] -- (Note: Available in Hive 0.6.0 and later)
]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)] -- (Note: Available in Hive 0.6.0 and later)
[AS select_statement]; -- (Note: Available in Hive 0.5.0 and later; not supported for external tables)

CREATE TABLE emp2 LIKE emp;
CREATE TABLE emp3 as select * from emp;

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];
1
2
3
4
5
6
7
8
9
10
CREATE EXTERNAL TABLE emp_external2(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/mydata/hive_external_table/emp/';

加载数据

local: “本地” linux服务器
无local:从HDFS

1
LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' into table emp;

分区

分区表 : 分区其实对应的就是HDFS上的一个文件夹/目录
分区前后IO的开销不是一个级别的
log
day=90121229
day=90121230

分区后指定分区查询会有很好的性能(磁盘IO 网络IO)
分区列并不是一个“真正的”表字段,其实是HDFS上表对应的文件夹下的一个文件夹

order_created.txt
订单号 订单产生时间

1
2
3
4
5
10703007267488	2014-05-01 06:01:12.334+01
10101043505096 2014-05-01 07:28:12.342+01
10103043509747 2014-05-01 07:50:12.33+01
10103043501575 2014-05-01 09:27:12.33+01
10104043514061 2014-05-01 09:03:12.324+01

分区表加载数据一定要指定分区字段

1
2
3
4
5
6
create table order_partition(
order_no string,
event_time string
)
PARTITIONED BY (event_month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
1
LOAD DATA LOCAL INPATH '/home/hadoop/data/order_created.txt' INTO TABLE order_partition PARTITION (event_month='2014-05');

对于分区表操作,如果你的数据是直接写入HDFS,比如由flume自动创建目录和文件
默认sql是查询不到的,
为什么?因为元数据里没有;需要以下方式刷元数据:

1
ALTER TABLE order_partition ADD IF NOT EXISTS PARTITION(event_month='2014-07') ;

单级分区 一层目录
二级分区 二层目录
三级分区 三层目录

1
2
3
4
5
6
7
8
9
create table order_mulit_partition(
order_no string,
event_time string
)
PARTITIONED BY (event_month string, step string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

**使用分区表时,加载数据一定要指定我们的所有分区字段**
LOAD DATA LOCAL INPATH '/home/hadoop/data/order_created.txt' INTO TABLE order_mulit_partition PARTITION (event_month='2014-05',step='1');

把emp的数据加载到emp分区表中去,分区字段是deptno

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE emp_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double
)
PARTITIONED BY (deptno int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

INSERT OVERWRITE TABLE emp_partition PARTITION (deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp where deptno=10;

动态分区

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE emp_dynamic_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double
)
PARTITIONED BY (deptno int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

INSERT OVERWRITE TABLE emp_dynamic_partition PARTITION (deptno) select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp;

DML

insert

1
2
3
4
5
LOAD DATA LOCAL INPATH '/home/hadoop/data/order_created.txt' [OVERWRITE] INTO TABLE order_mulit_partition PARTITION (event_month='2014-05',step='1');
LOAD DATA : 加载数据
LOCAL: "本地" 没有的话就HDFS
INPATH: 指定路径
OVERWRITE:数据覆盖 没有的话就是追加

CTAS : create table .. as select…
表不能事先存在

insert:
表必须事先存在
insert overwrite table emp4 select empno,job,ename,mgr,hiredate,sal,comm,deptno from emp;

SELECT

1
2
3
4
5
6
7
8
9
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT [offset,] rows]

常用函数

1、like rlike

1
2
3
4
5
6
#第二个数字是2的
select * from emp where sal like '_2%';
#包含2
select * from emp where sal like '%2%';
#包含2
select * from emp where sal rlike '[2]';

2、聚合: 多进一出
max
min
count
sum
avg

3、group by

求每个部门的平均工资 大于2000

select deptno,avg(sal) avg_sal from emp group by deptno having avg_sal>2000;

select中出现的字段,如果没有出现在group by中,必须出现在聚合函数中

4、where和having的区别

“Where”是一个约束声明,在查询数据库的结果返回之前对数据库中的查询条件进行约束,即在结果返回之前起作用,且where后面不能使用“聚合函数”;

“Having”是一个过滤声明,所谓过滤是在查询数据库的结果返回之后进行过滤,即在结果返回之后起作用,并且having后面可以使用“聚合函数”。

5、作业计算引擎
参数 hive.fetch.task.conversion=more 0.14之后默认
more是有简单的不会跑mapreduce,比如 select * 、filter在分区列
如果设定none 所有任务都会跑mapreduce
minimal select\filter\limit等